var listConfig = {}, createChild, removeChildList = {};

function render(parentNode, isLoad) {
    var { start, end, pagesize } = listConfig;
    if (isLoad === undefined) {
        // 初始化
        for (var i = 0; i < Math.min(listConfig.max, end); i++) {
            parentNode.appendChild(createChild(i));
        }
    } else if (isLoad) {
        if (start > 0 && listConfig.ismore) {
            // 初始化计数器
            var count = 0;
            // 循环遍历 <ul> 中的 <li> 元素
            while (count < pagesize && parentNode.firstChild) {
                var node = parentNode.firstChild;
                removeChildList[node.getAttribute('data-idx')] = node;
                // 删除第一个 <li> 元素
                parentNode.removeChild(parentNode.firstChild);
                // 增加计数器
                count++;
            }
        }
        console.log(start + pagesize * 2, end);
        for (var startIdx = start + pagesize * 2; startIdx < Math.min(listConfig.max, end); startIdx++) {
            parentNode.appendChild(createChild(startIdx));
        }
    } else {
        // 初始化计数器
        var count = 0;
        // 循环遍历 <ul> 中的 <li> 元素
        while (count < pagesize && parentNode.lastChild) {
            var node = parentNode.lastChild;
            removeChildList[node.getAttribute('data-idx')] = node;
            // 删除第一个 <li> 元素
            parentNode.removeChild(node);
            // 增加计数器
            count++;
        }
        console.log("当前第一个节点", parentNode.firstChild);
        for (var i = pagesize; i > 0; i--) {
            var node = createChild(start + i - 1);
            console.log('往前插入的节点：', node);
            parentNode.insertBefore(node, parentNode.firstChild);
        }
    }
    lastTop = parentNode.scrollTop;
}

/**
 *
 * @param {*} el 监听滚动的元素
 * @param {*} isLoad 是否滚动向下加载
 */
var lastTop = 0;
function isScrollToLast(el) {
    const initialTop = el.getBoundingClientRect().top;
    var currentTop = el.scrollTop;
    var isLoad = lastTop < currentTop;
    lastTop = currentTop;
    var { start, pagesize } = listConfig;
    if (isLoad) {
        if (!listConfig.ismore) {
            return;
        }
        var idx = start < 0 ? 15 : pagesize * 2 - 1;
        var child = el.children[idx];
        var rectBottom = child.getBoundingClientRect().bottom;
        // 判断目标节点的底部是否在ul这个容器的高度+初始偏移高度之上
        if (rectBottom <= initialTop + el.clientHeight) {
            listConfig.start = start + pagesize;
            render(el, isLoad);
        }
    } else {
        if (start <= 0) {
            return;
        }
        var li = el.children[pagesize + 1];
        var rectTop = li.getBoundingClientRect().top;
        if (rectTop > initialTop) {
            listConfig.start = start - pagesize;
            render(el, false);
        }
    }
}
/**
 * 节流
 * @param fn 要进行节流的函数
 * @param time 节流多少时间触发，默认为100ms
 */
function throttle(fn, time = 0.1 * 1000) {
    let cxt = this, timeTag = Date.now(), a;
    return function(...args) {
        // 时间间隔小于固定间隔时，直接跳过
        let date = Date.now();
        if(date - timeTag < time) {
            return;
        }
        // 更新timeTag
        timeTag = date;
        fn.apply(cxt, args);
    }
}
function handleScroll(el) {
    throttle(isScrollToLast(el.target));
}
function initVirturalList(parentNode, createChildFn, _listConfig) {
    listConfig = _listConfig || { pagesize: 15, max: 0 };
    listConfig.start = 0 - listConfig.pagesize;
    Object.defineProperties(listConfig, {
        'end': {
            get: function () {
                return listConfig.pagesize * 3 + listConfig.start;
            },
        },
        'ismore': {
            get: function() {
                return listConfig.max > listConfig.end
            }
        }
    })
    Object.defineProperty(listConfig, 'end', {
    });
    createChild = function(index) {
        if (removeChildList[index]) {
            var node = removeChildList[index];
            delete removeChildList[index];
            return node;
        }
        var node = createChildFn.apply(this, [index]);
        node.setAttribute('data-idx', index);
        return node;
    };
    parentNode.addEventListener('scroll', handleScroll);
    render(parentNode);
}
